iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Modern Web

Modern Web:從基礎、框架到前端學習系列 第 21

Day 21:登入系統 (表單驗證 + API 整合)

  • 分享至 

  • xImage
  •  

學習目標

  1. 建立一個登入表單,並進行即時驗證(必填、格式檢查)。
  2. 使用 API 來模擬登入請求。
  3. 學習**Token-based Authentication (JWT)**的基本概念。
  4. 完成「登入成功 → 儲存 Token → 顯示歡迎頁」的流程。

重點整理

1. JWT 身分驗證流程(簡化版)

  1. 使用者輸入帳號密碼,前端送到後端 API。
  2. 後端驗證成功後,回傳一個JWT Token
  3. 前端把 Token 存在localStoragesessionStorage
  4. 之後每次請求 API,都要在 Header 加上:
Authorization: Bearer <token>

2. 假登入 API

我們用一個常見的測試 API 來模擬登入:

https://reqres.in/api/login

  • 方法POST
  • Body 範例
{
  "email": "eve.holt@reqres.in",
  "password": "cityslicka"
}
  • 成功回應
{
  "token": "QpwL5tke4Pnpja7X4"
}

今日小專案:登入系統 Demo

專案結構

login-demo/
  ├── index.html
  ├── style.css
  └── script.js

index.html

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="UTF-8">
  <title>登入系統 Demo</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>登入系統</h1>
  <form id="loginForm">
    <div>
      <label for="email">Email:</label>
      <input type="email" id="email" placeholder="輸入 Email" required>
      <span class="error" id="emailError"></span>
    </div>
    <div>
      <label for="password">密碼:</label>
      <input type="password" id="password" placeholder="輸入密碼" required>
      <span class="error" id="passwordError"></span>
    </div>
    <button type="submit">登入</button>
  </form>

  <div id="welcome" style="display:none;">
    <h2>🎉 歡迎登入成功!</h2>
    <p id="tokenInfo"></p>
    <button id="logout">登出</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

style.css

body {
  font-family: Arial, sans-serif;
  max-width: 400px;
  margin: 50px auto;
  text-align: center;
}

form div {
  margin-bottom: 15px;
}

input {
  padding: 8px;
  width: 90%;
}

button {
  padding: 10px 15px;
  cursor: pointer;
}

.error {
  color: red;
  font-size: 12px;
}

script.js

const loginForm = document.getElementById('loginForm');
const emailInput = document.getElementById('email');
const passwordInput = document.getElementById('password');
const emailError = document.getElementById('emailError');
const passwordError = document.getElementById('passwordError');
const welcomeDiv = document.getElementById('welcome');
const tokenInfo = document.getElementById('tokenInfo');
const logoutBtn = document.getElementById('logout');

// 假登入 API
const API_URL = 'https://reqres.in/api/login';

// 簡單表單驗證
function validateForm() {
  let valid = true;
  emailError.textContent = '';
  passwordError.textContent = '';

  if (!emailInput.value.includes('@')) {
    emailError.textContent = '請輸入正確的 Email 格式';
    valid = false;
  }
  if (passwordInput.value.length < 6) {
    passwordError.textContent = '密碼至少需要 6 位數';
    valid = false;
  }
  return valid;
}

// 登入流程
loginForm.addEventListener('submit', (e) => {
  e.preventDefault();

  if (!validateForm()) return;

  axios.post(API_URL, {
    email: emailInput.value,
    password: passwordInput.value
  })
  .then(res => {
    const token = res.data.token;
    localStorage.setItem('authToken', token);

    loginForm.style.display = 'none';
    welcomeDiv.style.display = 'block';
    tokenInfo.textContent = `登入成功!Token: ${token}`;
  })
  .catch(err => {
    alert('登入失敗,請檢查帳號密碼');
    console.error(err);
  });
});

// 登出
logoutBtn.addEventListener('click', () => {
  localStorage.removeItem('authToken');
  welcomeDiv.style.display = 'none';
  loginForm.style.display = 'block';
});

今日成果

  • 建立了一個完整的登入系統 Demo
  • 熟悉了前端表單驗證+API 整合
  • 學會將JWT Token 儲存並用於後續請求
  • 知道了登入 / 登出流程的基本概念

📌思考延伸

  • 如果要在登入後,才能看到某些頁面,要如何做「路由守衛」?
  • Token 存在localStoragevscookie有什麼差異與安全性問題?

上一篇
Day 20:RESTful API 設計與整合
系列文
Modern Web:從基礎、框架到前端學習21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言